package com.joeyzh.imagepicker.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by Joey on 2017/9/21.
 * 图片压缩处理的工具类
 */

public class CompressBitmapUtils {

    //计算图片的缩放值
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }


    public static Bitmap.CompressFormat getCompressFormat(String filePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        if (options.outMimeType.equals("image/png")) {
//            LogUtils.a("png");
            return Bitmap.CompressFormat.PNG;
        }
        return Bitmap.CompressFormat.JPEG;
    }

    public static String compressImage(String filePath, String targetPath, int quality) {
        Bitmap bm = getSmallBitmap(filePath);//获取一定尺寸的图片
//        int degree = readPictureDegree(filePath);//获取相片拍摄角度
//        if (degree != 0) {//旋转照片角度，防止头像横着显示
//            bm = rotateBitmap(bm, degree);
//        }
        Bitmap.CompressFormat format = getCompressFormat(filePath);

        File outputFile = new File(targetPath);
        try {
            if (!outputFile.exists()) {
                outputFile.getParentFile().mkdirs();
                //outputFile.createNewFile();
            } else {
                outputFile.delete();
            }
            FileOutputStream out = new FileOutputStream(outputFile);
            bm.compress(format, quality, out);
        } catch (Exception e) {

        }
        return outputFile.getPath();
    }


    public static Bitmap compressBitmap(String filePath) {
        Bitmap bitmap = getSmallBitmap(filePath);
//        int degree = readPictureDegree(filePath);//获取相片拍摄角度
//        if (degree != 0) {//旋转照片角度，防止头像横着显示
//            bitmap = rotateBitmap(bitmap, degree);
//        }
        Bitmap.CompressFormat format = getCompressFormat(filePath);
        ByteArrayOutputStream baos = compressBitmap(bitmap, format);
        return BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.toByteArray().length);
    }

    /**
     *  
     *  * 图片按比例大小压缩方法 
     *  * 
     *  * @param image （根据Bitmap图片压缩） 
     *  * @return 
     *  
     */
    public static Bitmap compressScale(Bitmap image) {
        //现在主流手机比较多是800*480分辨率，所以高和宽我们设置为
        //这里设置高度为800f  宽度为480f
        return compressScale(image, 800, 480);
    }

    /**
     * 根据路径获得图片信息并按比例压缩，返回bitmap
     */
    public static Bitmap getSmallBitmap(String filePath) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//只解析图片边沿，获取宽高
        BitmapFactory.decodeFile(filePath, options);
        // 计算缩放比
        options.inSampleSize = calculateInSampleSize(options, 480, 800);
        // 完整解析图片返回bitmap
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }


    /**
     * 获取照片角度
     *
     * @param path
     * @return
     */
    public static int readPictureDegree(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(
                    ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 旋转照片
     *
     * @param bitmap
     * @param degress
     * @return
     */
    public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {
        if (bitmap != null) {
            Matrix m = new Matrix();
            m.postRotate(degress);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                    bitmap.getHeight(), m, true);
            return bitmap;
        }
        return bitmap;
    }

    /**
     * 图片按比例大小压缩方法 
     *
     * @param image  根据Bitmap图片压缩
     * @param height 高度
     * @param width  宽度
     * @return
     */
    public static Bitmap compressScale(Bitmap image, int height, int width) {
        ByteArrayOutputStream baos = compressBitmap(image,Bitmap.CompressFormat.JPEG);
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片，此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        //设置缩放比例
        newOpts.inSampleSize = calculateInSampleSize(newOpts, width, height);

        // 降低图片从ARGB888到RGB565
        //重新读入图片，注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        return bitmap;
    }

    /**
     * 压缩图片
     *
     * @param bitmap 根据Bitmap图片压缩
     * @param format 图像的压缩格式
     * @return
     */
    private static ByteArrayOutputStream compressBitmap(Bitmap bitmap, Bitmap.CompressFormat format) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int compressOptions = 100;
        //质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        bitmap.compress(format, compressOptions, baos);
        //循环判断如果压缩后图片是否大于100kb,大于继续压缩
        while ((baos.toByteArray().length >> 10) > 100 && compressOptions > 1) {
            //每次都减少10
            compressOptions -= 10;
            if (compressOptions <= 0) {
                compressOptions = 1;
            }
            //重置baos即清空baos
            baos.reset();
            //这里压缩options%，把压缩后的数据存放到baos中
            bitmap.compress(Bitmap.CompressFormat.JPEG, compressOptions, baos);
        }
        return baos;
    }

}
